﻿using AutoMapper;
using Medical.Domain.RBAC;
using Medical.ErrorCode;
using Medical.Interstructrue;
using Medical.Interstructrue.Base;
using Microsoft.EntityFrameworkCore.Storage;
using System.Linq;

namespace Medical.Api.Write.Service.RBAC
{
    public class RBACService : IRBACService
    {
        private readonly IBaseRepository<PermissionModel> _permissionRepository;
        private readonly IBaseRepository<RoleModel> _roleRepository;
        private readonly IBaseRepository<UserModel> _userRepository;
        private readonly IBaseRepository<RolePermissionModel> _rolePermissionRepository;
        private readonly IBaseRepository<UserRoleModel> _userRoleRepository;
        private readonly MedicalDbContext _dbContext;
        private readonly IMapper mapper;
        private readonly ILogger<RBACService> _logger;

        public RBACService(IBaseRepository<PermissionModel> permissionRepository, IBaseRepository<RoleModel> roleRepository, IBaseRepository<UserModel> userRepository, IBaseRepository<RolePermissionModel> rolePermissionRepository, IBaseRepository<UserRoleModel> userRoleRepository, MedicalDbContext dbContext, IMapper mapper, ILogger<RBACService> logger)
        {
            _permissionRepository = permissionRepository;
            _roleRepository = roleRepository;
            _userRepository = userRepository;
            _rolePermissionRepository = rolePermissionRepository;
            _userRoleRepository = userRoleRepository;
            _dbContext = dbContext;
            this.mapper = mapper;
            _logger = logger;
        }
        /// <summary>
        /// 创建权限
        /// </summary>
        /// <param name="permission"></param>
        /// <returns></returns>
        public ApiResult<int> CreatePermission(PermissionModel permission)
        {
            ApiResult<int> result = new ApiResult<int>();
            if (_permissionRepository.GetAll().Any(p => p.PermissionName == permission.PermissionName && !p.IsDeleted))
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "权限名已存在";
                return result;
            }
            var r = _permissionRepository.Create(permission);
            if (r > 0)
            {
                result.Data = r;
                result.Code = ApiEnums.Success;
                result.Msg = "创建权限成功";
                _logger.LogInformation("创建权限成功");
                return result;
            }
            else
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "创建权限失败";
                result.Data = r;
                _logger.LogError("创建权限失败");
                return result;
            }
        }

        /// <summary>
        /// 创建角色并分配权限
        /// </summary>
        /// <param name="role">角色信息</param>
        /// <param name="PermissionIds">权限ID列表</param>
        /// <returns></returns>
        public ApiResult<int> CreateRole(RoleModel role, List<int> PermissionIds)
        {
            ApiResult<int> result = new ApiResult<int>();
            if (_roleRepository.GetAll().Any(r => r.RoleName == role.RoleName && !r.IsDeleted))
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "角色名已存在";
                return result;
            }
            try
            {
                using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        int roleId = _roleRepository.Create(role);
                        if (roleId <= 0)
                        {
                            result.Code = ApiEnums.Fail;
                            result.Msg = "创建角色失败";
                            result.Data = roleId;
                            _logger.LogError("创建角色失败");
                            return result;
                        }
                        if (PermissionIds != null && PermissionIds.Any())
                        {
                            foreach (int permissionId in PermissionIds.Distinct())
                            {
                                if (_rolePermissionRepository.GetAll().Any(rp => rp.RoleId == roleId && rp.PermissionId == permissionId && !rp.IsDeleted))
                                    continue;
                                RolePermissionModel rolePermission = new RolePermissionModel
                                {
                                    RoleId = roleId,
                                    PermissionId = permissionId
                                };
                                int rolePermissionResult = _rolePermissionRepository.Create(rolePermission);
                                if (rolePermissionResult <= 0)
                                {
                                    transaction.Rollback();
                                    result.Code = ApiEnums.Fail;
                                    result.Msg = $"添加角色权限关联失败，权限ID: {permissionId}";
                                    result.Data = 0;
                                    _logger.LogError($"添加角色权限关联失败，权限ID: {permissionId}");
                                    return result;
                                }
                            }
                        }
                        transaction.Commit();
                        result.Data = roleId;
                        result.Code = ApiEnums.Success;
                        result.Msg = "创建角色并分配权限成功";
                        _logger.LogInformation($"创建角色成功，角色ID: {roleId}，分配权限数量: {PermissionIds?.Count ?? 0}");
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        result.Code = ApiEnums.Fail;
                        result.Msg = $"创建角色过程中发生异常: {ex.Message}";
                        result.Data = 0;
                        _logger.LogError(ex, "创建角色过程中发生异常");
                    }
                }
            }
            catch (Exception ex)
            {
                result.Code = ApiEnums.Fail;
                result.Msg = $"创建角色失败: {ex.Message}";
                result.Data = 0;
                _logger.LogError(ex, "创建角色失败");
            }
            return result;
        }

        /// <summary>
        /// 创建用户并分配角色
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <param name="RoleIds">角色ID列表</param>
        /// <returns></returns>
        public ApiResult<int> CreateUser(UserModel user, List<int> RoleIds)
        {
            ApiResult<int> result = new ApiResult<int>();
            if (_userRepository.GetAll().Any(u => u.UserName == user.UserName && !u.IsDeleted))
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "用户名已存在";
                return result;
            }
            try
            {
                using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        int userId = _userRepository.Create(user);
                        if (userId <= 0)
                        {
                            result.Code = ApiEnums.Fail;
                            result.Msg = "创建用户失败";
                            result.Data = userId;
                            _logger.LogError("创建用户失败");
                            return result;
                        }
                        if (RoleIds != null && RoleIds.Any())
                        {
                            foreach (int roleId in RoleIds.Distinct())
                            {
                                if (_userRoleRepository.GetAll().Any(ur => ur.UserId == userId && ur.RoleId == roleId && !ur.IsDeleted))
                                    continue;
                                UserRoleModel userRole = new UserRoleModel
                                {
                                    UserId = userId,
                                    RoleId = roleId
                                };
                                int userRoleResult = _userRoleRepository.Create(userRole);
                                if (userRoleResult <= 0)
                                {
                                    transaction.Rollback();
                                    result.Code = ApiEnums.Fail;
                                    result.Msg = $"添加用户角色关联失败，角色ID: {roleId}";
                                    result.Data = 0;
                                    _logger.LogError($"添加用户角色关联失败，角色ID: {roleId}");
                                    return result;
                                }
                            }
                        }
                        transaction.Commit();
                        result.Data = userId;
                        result.Code = ApiEnums.Success;
                        result.Msg = "创建用户并分配角色成功";
                        _logger.LogInformation($"创建用户成功，用户ID: {userId}，分配角色数量: {RoleIds?.Count ?? 0}");
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        result.Code = ApiEnums.Fail;
                        result.Msg = $"创建用户过程中发生异常: {ex.Message}";
                        result.Data = 0;
                        _logger.LogError(ex, "创建用户过程中发生异常");
                    }
                }
            }
            catch (Exception ex)
            {
                result.Code = ApiEnums.Fail;
                result.Msg = $"创建用户失败: {ex.Message}";
                result.Data = 0;
                _logger.LogError(ex, "创建用户失败");
            }
            return result;
        }
        // 修改用户（逻辑删除原有用户及其角色关系，重新插入新用户和新用户角色，事务）
        public ApiResult<int> UpdateUser(UserModel user)
        {
            var result = new ApiResult<int>();
            using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    var exist = _userRepository.GetlongModel(user.Id);
                    if (exist == null || exist.IsDeleted)
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "用户不存在";
                        return result;
                    }
                    // 用户名唯一性校验
                    if (_userRepository.GetAll().Any(u => u.UserName == user.UserName && u.Id != user.Id && !u.IsDeleted))
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "用户名已存在";
                        return result;
                    }
                    // 逻辑删除原有用户
                    exist.IsDeleted = true;
                    _userRepository.Update(exist);
                    // 逻辑删除原有用户角色关系
                    var userRoles = _userRoleRepository.GetAll().Where(ur => ur.UserId == user.Id && !ur.IsDeleted).ToList();
                    foreach (var ur in userRoles)
                    {
                        ur.IsDeleted = true;
                        _userRoleRepository.Update(ur);
                    }
                    // 新增新用户（新Id）
                    var newUser = new UserModel
                    {
                        UserName = user.UserName,
                        Password = user.Password,
                        CreateTime = DateTime.Now,
                        IsDeleted = false
                    };
                    int newUserId = _userRepository.Create(newUser);
                    if (newUserId <= 0)
                    {
                        transaction.Rollback();
                        result.Code = ApiEnums.Fail;
                        result.Msg = "用户修改失败";
                        return result;
                    }
                    // 新增用户角色关系
                    if (user is UserModel u && u.Id > 0)
                    {
                        // 这里假设前端传递了RoleIds字段
                        var roleIds = user.GetType().GetProperty("RoleIds")?.GetValue(user) as List<int>;
                        if (roleIds != null && roleIds.Any())
                        {
                            foreach (var roleId in roleIds.Distinct())
                            {
                                if (_userRoleRepository.GetAll().Any(ur => ur.UserId == newUserId && ur.RoleId == roleId && !ur.IsDeleted))
                                    continue;
                                var userRole = new UserRoleModel
                                {
                                    UserId = newUserId,
                                    RoleId = roleId,
                                    CreateTime = DateTime.Now,
                                    IsDeleted = false
                                };
                                _userRoleRepository.Create(userRole);
                            }
                        }
                    }
                    transaction.Commit();
                    result.Data = newUserId;
                    result.Code = ApiEnums.Success;
                    result.Msg = "修改成功";
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result.Code = ApiEnums.Fail;
                    result.Msg = $"修改用户失败: {ex.Message}";
                }
            }
            return result;
        }
        // 逻辑删除用户及其用户角色关系（事务）
        public ApiResult<int> DeleteUser(int userId)
        {
            var result = new ApiResult<int>();
            using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    var user = _userRepository.GetModel(userId);
                    if (user == null || user.IsDeleted)
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "用户不存在";
                        return result;
                    }
                    user.IsDeleted = true;
                    _userRepository.Update(user);
                    // 逻辑删除用户角色关系
                    var userRoles = _userRoleRepository.GetAll().Where(ur => ur.UserId == userId && !ur.IsDeleted).ToList();
                    foreach (var ur in userRoles)
                    {
                        ur.IsDeleted = true;
                        _userRoleRepository.Update(ur);
                    }
                    transaction.Commit();
                    result.Data = 1;
                    result.Code = ApiEnums.Success;
                    result.Msg = "删除成功";
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result.Code = ApiEnums.Fail;
                    result.Msg = $"删除用户失败: {ex.Message}";
                }
            }
            return result;
        }
        // 修改角色（逻辑删除原有角色及其权限关系，重新插入新角色和新角色权限，事务）
        public ApiResult<int> UpdateRole(RoleModel role)
        {
            var result = new ApiResult<int>();
            using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    var exist = _roleRepository.GetlongModel(role.Id);
                    if (exist == null || exist.IsDeleted)
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "角色不存在";
                        return result;
                    }
                    // 角色名唯一性校验
                    if (_roleRepository.GetAll().Any(r => r.RoleName == role.RoleName && r.Id != role.Id && !r.IsDeleted))
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "角色名已存在";
                        return result;
                    }
                    // 逻辑删除原有角色
                    exist.IsDeleted = true;

                    _roleRepository.Update(exist);
                    // 逻辑删除原有角色权限关系
                    var rolePermissions = _rolePermissionRepository.GetAll().Where(rp => rp.RoleId == role.Id && !rp.IsDeleted).ToList();
                    foreach (var rp in rolePermissions)
                    {
                        rp.IsDeleted = true;

                        _rolePermissionRepository.Update(rp);
                    }
                    // 新增新角色（新Id）
                    var newRole = new RoleModel
                    {
                        RoleName = role.RoleName,
                        CreateTime = DateTime.Now,
                        IsDeleted = false
                    };
                    int newRoleId = _roleRepository.Create(newRole);
                    if (newRoleId <= 0)
                    {
                        transaction.Rollback();
                        result.Code = ApiEnums.Fail;
                        result.Msg = "角色修改失败";
                        return result;
                    }
                    // 新增角色权限关系
                    if (role is RoleModel r && r.Id > 0)
                    {
                        // 这里假设前端传递了PermissionIds字段
                        var permissionIds = role.GetType().GetProperty("PermissionIds")?.GetValue(role) as List<int>;
                        if (permissionIds != null && permissionIds.Any())
                        {
                            foreach (var permissionId in permissionIds.Distinct())
                            {
                                if (_rolePermissionRepository.GetAll().Any(rp => rp.RoleId == newRoleId && rp.PermissionId == permissionId && !rp.IsDeleted))
                                    continue;
                                var rolePermission = new RolePermissionModel
                                {
                                    RoleId = newRoleId,
                                    PermissionId = permissionId,
                                    CreateTime = DateTime.Now,
                                    IsDeleted = false
                                };
                                _rolePermissionRepository.Create(rolePermission);
                            }
                        }
                    }
                    transaction.Commit();
                    result.Data = newRoleId;
                    result.Code = ApiEnums.Success;
                    result.Msg = "修改成功";
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result.Code = ApiEnums.Fail;
                    result.Msg = $"修改角色失败: {ex.Message}";
                }
            }
            return result;
        }
        // 逻辑删除角色及其角色权限关系（事务）
        public ApiResult<int> DeleteRole(int roleId)
        {
            var result = new ApiResult<int>();
            using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    var role = _roleRepository.GetModel(roleId);
                    if (role == null || role.IsDeleted)
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "角色不存在";
                        return result;
                    }
                    role.IsDeleted = true;

                    _roleRepository.Update(role);
                    // 逻辑删除角色权限关系
                    var rolePermissions = _rolePermissionRepository.GetAll().Where(rp => rp.RoleId == roleId && !rp.IsDeleted).ToList();
                    foreach (var rp in rolePermissions)
                    {
                        rp.IsDeleted = true;

                        _rolePermissionRepository.Update(rp);
                    }
                    transaction.Commit();
                    result.Data = 1;
                    result.Code = ApiEnums.Success;
                    result.Msg = "删除成功";
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result.Code = ApiEnums.Fail;
                    result.Msg = $"删除角色失败: {ex.Message}";
                }
            }
            return result;
        }
        // 修改权限
        public ApiResult<int> UpdatePermission(PermissionModel permission)
        {
            var result = new ApiResult<int>();
            var exist = _permissionRepository.GetlongModel(permission.Id);
            if (exist == null || exist.IsDeleted)
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "权限不存在";
                return result;
            }
            // 权限名唯一性校验
            if (_permissionRepository.GetAll().Any(p => p.PermissionName == permission.PermissionName && p.Id != permission.Id && !p.IsDeleted))
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "权限名已存在";
                return result;
            }
            exist.PermissionName = permission.PermissionName;
            exist.PermissionURL = permission.PermissionURL;
            exist.ParentId = permission.ParentId;
            var r = _permissionRepository.Update(exist);
            result.Data = r;
            result.Code = r > 0 ? ApiEnums.Success : ApiEnums.Fail;
            result.Msg = r > 0 ? "修改成功" : "修改失败";
            return result;
        }
        // 逻辑删除权限
        public ApiResult<int> DeletePermission(int permissionId)
        {
            var result = new ApiResult<int>();
            var permission = _permissionRepository.GetModel(permissionId);
            if (permission == null || permission.IsDeleted)
            {
                result.Code = ApiEnums.Fail;
                result.Msg = "权限不存在";
                return result;
            }
            permission.IsDeleted = true;
            var r = _permissionRepository.Update(permission);
            result.Data = r;
            result.Code = r > 0 ? ApiEnums.Success : ApiEnums.Fail;
            result.Msg = r > 0 ? "删除成功" : "删除失败";
            return result;
        }
        // 检查用户名唯一
        public ApiResult<bool> CheckUserNameUnique(string userName, int? userId = null)
        {
            var exist = _userRepository.GetAll().Any(u => u.UserName == userName && (!userId.HasValue || u.Id != userId.Value) && !u.IsDeleted);
            return new ApiResult<bool> { Data = !exist, Code = exist ? ApiEnums.Fail : ApiEnums.Success, Msg = exist ? "用户名已存在" : "用户名可用" };
        }
        // 检查角色名唯一
        public ApiResult<bool> CheckRoleNameUnique(string roleName, int? roleId = null)
        {
            var exist = _roleRepository.GetAll().Any(r => r.RoleName == roleName && (!roleId.HasValue || r.Id != roleId.Value) && !r.IsDeleted);
            return new ApiResult<bool> { Data = !exist, Code = exist ? ApiEnums.Fail : ApiEnums.Success, Msg = exist ? "角色名已存在" : "角色名可用" };
        }
        // 检查权限名唯一
        public ApiResult<bool> CheckPermissionNameUnique(string permissionName, int? permissionId = null)
        {
            var exist = _permissionRepository.GetAll().Any(p => p.PermissionName == permissionName && (!permissionId.HasValue || p.Id != permissionId.Value) && !p.IsDeleted);
            return new ApiResult<bool> { Data = !exist, Code = exist ? ApiEnums.Fail : ApiEnums.Success, Msg = exist ? "权限名已存在" : "权限名可用" };
        }
    }
}
